//
//  ViewController.m
//  MVVMFoundation
//
//  Created by hulinhu on 2017/12/21.
//  Copyright © 2017年 hulinhu. All rights reserved.
//

#import "ViewController.h"
#import <ReactiveObjC/ReactiveObjC.h>
#import "HLDelegateView.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UITextField *textFiled;
@property (weak, nonatomic) IBOutlet UIButton *button;

@property (nonatomic, strong) RACDisposable *disposable;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    HLDelegateView *delegateView = [[HLDelegateView alloc] initWithFrame:CGRectMake(0, 300, 375, 100)];
    delegateView.backgroundColor = [UIColor yellowColor];
    [self.view addSubview:delegateView];
    // 订阅代理信号, 方式一设置代理信号
    delegateView.delegateSignal = [RACSubject subject];
    [delegateView.delegateSignal subscribeNext:^(id  _Nullable x) {
        self.view.backgroundColor = x ? [UIColor orangeColor] : [UIColor whiteColor];
    }];
    
//    [delegateView.btnCommand.executionSignals.switchToLatest subscribeNext:^(id  _Nullable x) {
//        NSLog(@" --- %@",x);
//
//    }];
    
    RACSignal *signal = [delegateView.btnCommand execute:@{}];
    [signal subscribeNext:^(id  _Nullable x) {
        NSLog(@" --- %@",x);

    }];
    NSLog(@" --- %p",signal);

    
    // 订阅代理信号, 方式二
    [[delegateView rac_signalForSelector:@selector(singbtnClick:)] subscribeNext:^(RACTuple * _Nullable x) {
        NSLog(@" --- 回调 字符串 %@ ",x);
    }];  
    
    
//    [self RACTextFieldFunction];
//    [self RACButtonFunction];
//    [self RACObserverFunction];
//    [self RACNotificationFunction];
//    [self RACKVOFunction];
}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
//    [self  RACSignalFunction];
//    [self RACSubjectFunction];
//    [self RACTupleFunction];
//    [self RACSequenceFunction];
//    [self RACSignalForSelectorFunction];
//    self.view.frame = CGRectMake(0, 0, 375, 800);
//    [self RACNSTimerFunction];
    
}

// 可以代替 NSTimer 使用
-(void)RACNSTimerFunction{
    
    /* 定义计时器监听 */
    self.disposable = [[RACSignal interval:1.0 onScheduler:[RACScheduler mainThreadScheduler]] subscribeNext:^(NSDate * _Nullable x) {
        NSLog(@"当前时间：%@", x); // x 是当前的系统时间
        /* 关闭计时器 */
        [_disposable dispose];
    }];
}

//  代替 KVO 监听
-(void)RACKVOFunction{
    
    // 可以代替 KVO 监听，下面表示把监听 view 的 frame 属性改变转换成信号，只要值改变就会发送信号。
    // 方式一
    [[self.view rac_valuesForKeyPath:@"frame" observer:self] subscribeNext:^(id  _Nullable x) {
        NSLog(@"属性的改变：%@", x); // x 是监听属性的改变结果
    }];
    
     // 方式二
    [RACObserve(self.view, frame) subscribeNext:^(id  _Nullable x) {
        NSLog(@"属性的改变：%@", x); // x 是监听属性的改变结果
    }];
    
}

//  代替 Delegate 代理方法
-(void)RACSignalForSelectorFunction{
    [[self rac_signalForSelector:@selector(btnClick)] subscribeNext:^(RACTuple * _Nullable x) {
        NSLog(@" view 中的按钮被点击了");
    }];
}
-(void)btnClick {
      NSLog(@" btnClick ---- ");
    
}

// 监听 按钮是否可以点击
-(void)RACNotificationFunction {
    
    [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardDidShowNotification object:nil] subscribeNext:^(NSNotification * _Nullable x) {
        NSLog(@"%@ 键盘弹起", x); // x 是通知对象
        [self btnClick];
    }];
}


// 监听 按钮是否可以点击
-(void)RACObserverFunction {
    RAC(self.button, enabled) = [RACSignal combineLatest:@[self.textFiled.rac_textSignal,] reduce:^id _Nullable(NSString * username){
        return @(username.length);
    }];
    
}

-(void)RACButtonFunction{
    
    // 可以省去 addTarget 添加事件和创建方法的步骤。
    [[self.button rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
        NSLog(@"%@ 按钮被点击了", x); // x 是 button 按钮对象
    }];
}


// textField 监听
-(void)RACTextFieldFunction{
    /* 监听 TextField 的输入（内容改变就会调用） */
    [[self.textFiled rac_textSignal] subscribeNext:^(NSString * _Nullable x) {
        NSLog(@"输入框内容：%@", x);
    }];
    
    /* 添加监听条件 */
    // 过滤
    [[self.textFiled.rac_textSignal filter:^BOOL(NSString * _Nullable value) {
        return value.length > 5; // 表示输入文字长度 > 5 时才会调用下面的 block
    }] subscribeNext:^(NSString * _Nullable x) {
        NSLog(@"输入框内容：%@", x);
    }];
    
}
// 遍历
-(void)RACSequenceFunction{
    
    /* 遍历数组 */
    NSArray *array = @[@"1", @"2", @"3", @"4", @"5"];
    [array.rac_sequence.signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"数组内容：%@", x); // x 可以是任何对象
    }];
    
    /* 遍历字典 */
    NSDictionary *dictionary = @{@"key1":@"value1", @"key2":@"value2", @"key3":@"value3"};
    [dictionary.rac_sequence.signal subscribeNext:^(RACTuple * _Nullable x) {
        RACTupleUnpack(NSString *key, NSString *value) = x; // x 是一个元祖，这个宏能够将 key 和 value 拆开
        NSLog(@"字典内容：%@:%@", key, value);
    }];
    
    
    /* 内容操作 */
    // 将所有内容替换为 0
    NSArray *array1 = @[@"1", @"2", @"3", @"4", @"5"];
    NSArray *newArray1 = [[array1.rac_sequence map:^id _Nullable(id  _Nullable value) {
        NSLog(@"数组内容：%@", value);
        return @"0"; // 将所有内容替换为 0
    }] array];
    
    NSLog(@"newArray1 ---- %@ ",newArray1);

    
    /* 内容快速替换 */
    NSArray *array2 = @[@"1", @"2", @"3", @"4", @"5"];
    NSArray *newArray2 = [[array2.rac_sequence mapReplace:@"0"] array]; // 将所有内容替换为 0
    NSLog(@"newArray2 ---- %@ ",newArray2);
}



-(void)RACTupleFunction{
    
//    RAC 的元祖，跟我们 OC 的数组其实是一样的，它其实就是封装了我们 OC 的数组。
    
    /* 创建元祖 */
    RACTuple *tuple = [RACTuple tupleWithObjects:@"1", @"2", @"3", @"4", @"5", nil];
    
    /* 从别的数组中获取内容 */
    RACTuple *tuple1 = [RACTuple tupleWithObjectsFromArray:@[@"1", @"2", @"3", @"4", @"5"]];
    
    /* 利用 RAC 宏快速封装 */
    RACTuple *tuple2 = RACTuplePack(@"1", @"2", @"3", @"4", @"5");
    
    NSLog(@"取元祖内容：%@", tuple[0]);
    NSLog(@"第一个元素：%@", [tuple1 first]);
    NSLog(@"最后一个元素：%@", [tuple2 last]);
    
}

-(void)RACSubjectFunction{
    
    // 和代理的用法类似，通常用来代替代理，有了它，就不必要定义代理了。
    // 特点：先订阅，后发送。
    
    /* 创建信号 */
    RACSubject *subject = [RACSubject subject];
    
    /* 订阅信号（通常在别的视图控制器中订阅，与代理的用法类似） */
    [subject subscribeNext:^(id  _Nullable x) {
        NSLog(@"信号内容：%@", x);
    }];
    
    /* 发送信号 */
    [subject sendNext:@"发送信号"];
    
}

-(void)RACSignalFunction{
    
   // RAC 的核心思想：创建信号 - 订阅信号 - 发送信号 ，并且在 RAC 中我们会看到大量的 block ，所以在使用之前可以再重新温习一下 block 的使用。
   // 特点：先订阅，后发送。
    
    /* 1 创建信号 */
    RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        /* 3 发送信号 */
        [subscriber sendNext:@"发送信号"];
        return nil;
    }];
    
    /* 2 订阅信号 */
    RACDisposable *disposable = [signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"信号内容：%@", x);
    }];
    
    /* 取消订阅 */
    [disposable dispose];
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end
